#include "BudgetManager.h"
#include <iostream>
#include <algorithm>
#include <iomanip>

BudgetManager::BudgetManager(const std::string& filename) : dataFile(filename) {
    loadFromFile();
}

bool BudgetManager::addIncome(const std::string& date, double amount,
                               const std::string& category, const std::string& note) {
    if (!Transaction::validateDate(date)) {
        std::cout << "错误：日期格式不正确！请使用 YYYY-MM-DD 格式。" << std::endl;
        return false;
    }
    if (!Transaction::validateAmount(amount)) {
        std::cout << "错误：金额必须为正数！" << std::endl;
        return false;
    }

    auto transaction = std::make_shared<Transaction>(date, amount, category, note, TransactionType::INCOME);
    transactions.push_back(transaction);
    std::cout << "收入记录添加成功！" << std::endl;
    saveToFile();
    return true;
}

bool BudgetManager::addExpense(const std::string& date, double amount,
                                const std::string& category, const std::string& note) {
    if (!Transaction::validateDate(date)) {
        std::cout << "错误：日期格式不正确！请使用 YYYY-MM-DD 格式。" << std::endl;
        return false;
    }
    if (!Transaction::validateAmount(amount)) {
        std::cout << "错误：金额必须为正数！" << std::endl;
        return false;
    }

    auto transaction = std::make_shared<Transaction>(date, amount, category, note, TransactionType::EXPENSE);
    transactions.push_back(transaction);
    std::cout << "支出记录添加成功！" << std::endl;
    saveToFile();
    return true;
}

void BudgetManager::displayAllTransactions() const {
    if (transactions.empty()) {
        std::cout << "暂无记录。" << std::endl;
        return;
    }

    std::cout << "\n========== 所有交易记录 ==========" << std::endl;
    for (const auto& trans : transactions) {
        trans->display();
    }
    std::cout << "================================" << std::endl;
}

void BudgetManager::displayByType(TransactionType type) const {
    std::string typeStr = (type == TransactionType::INCOME) ? "收入" : "支出";
    std::cout << "\n========== " << typeStr << "记录 ==========" << std::endl;

    bool found = false;
    for (const auto& trans : transactions) {
        if (trans->getType() == type) {
            trans->display();
            found = true;
        }
    }

    if (!found) {
        std::cout << "暂无" << typeStr << "记录。" << std::endl;
    }
    std::cout << "================================" << std::endl;
}

void BudgetManager::displayByCategory(const std::string& category) const {
    std::cout << "\n========== 类别：" << category << " ==========" << std::endl;

    bool found = false;
    for (const auto& trans : transactions) {
        if (trans->getCategory() == category) {
            trans->display();
            found = true;
        }
    }

    if (!found) {
        std::cout << "暂无该类别的记录。" << std::endl;
    }
    std::cout << "================================" << std::endl;
}

void BudgetManager::displayByDateRange(const std::string& startDate, const std::string& endDate) const {
    if (!Transaction::validateDate(startDate) || !Transaction::validateDate(endDate)) {
        std::cout << "错误：日期格式不正确！" << std::endl;
        return;
    }

    std::cout << "\n========== 日期范围：" << startDate << " 至 " << endDate << " ==========" << std::endl;

    bool found = false;
    for (const auto& trans : transactions) {
        if (trans->getDate() >= startDate && trans->getDate() <= endDate) {
            trans->display();
            found = true;
        }
    }

    if (!found) {
        std::cout << "该日期范围内暂无记录。" << std::endl;
    }
    std::cout << "================================" << std::endl;
}

double BudgetManager::getTotalIncome() const {
    double total = 0.0;
    for (const auto& trans : transactions) {
        if (trans->getType() == TransactionType::INCOME) {
            total += trans->getAmount();
        }
    }
    return total;
}

double BudgetManager::getTotalExpense() const {
    double total = 0.0;
    for (const auto& trans : transactions) {
        if (trans->getType() == TransactionType::EXPENSE) {
            total += trans->getAmount();
        }
    }
    return total;
}

double BudgetManager::getNetIncome() const {
    return getTotalIncome() - getTotalExpense();
}

void BudgetManager::displayStatisticsByCategory() const {
    if (transactions.empty()) {
        std::cout << "暂无记录可统计。" << std::endl;
        return;
    }

    std::map<std::string, double> incomeByCategory;
    std::map<std::string, double> expenseByCategory;

    for (const auto& trans : transactions) {
        if (trans->getType() == TransactionType::INCOME) {
            incomeByCategory[trans->getCategory()] += trans->getAmount();
        } else {
            expenseByCategory[trans->getCategory()] += trans->getAmount();
        }
    }

    std::cout << "\n========== 按类别统计 ==========" << std::endl;

    if (!incomeByCategory.empty()) {
        std::cout << "\n收入类别：" << std::endl;
        for (const auto& pair : incomeByCategory) {
            std::cout << "  " << pair.first << ": " << std::fixed << std::setprecision(2) << pair.second << std::endl;
        }
    }

    if (!expenseByCategory.empty()) {
        std::cout << "\n支出类别：" << std::endl;
        for (const auto& pair : expenseByCategory) {
            std::cout << "  " << pair.first << ": " << std::fixed << std::setprecision(2) << pair.second << std::endl;
        }
    }

    std::cout << "\n总收入: " << std::fixed << std::setprecision(2) << getTotalIncome() << std::endl;
    std::cout << "总支出: " << std::fixed << std::setprecision(2) << getTotalExpense() << std::endl;
    std::cout << "净收入: " << std::fixed << std::setprecision(2) << getNetIncome() << std::endl;
    std::cout << "================================" << std::endl;
}

void BudgetManager::displayMonthlyStatistics(const std::string& yearMonth) const {
    std::cout << "\n========== " << yearMonth << " 月度统计 ==========" << std::endl;

    double monthlyIncome = 0.0;
    double monthlyExpense = 0.0;
    int count = 0;

    // 统计各类别支出
    std::map<std::string, double> categoryExpenses;

    for (const auto& trans : transactions) {
        if (trans->getDate().substr(0, 7) == yearMonth) {
            if (trans->getType() == TransactionType::INCOME) {
                monthlyIncome += trans->getAmount();
            } else {
                monthlyExpense += trans->getAmount();
                categoryExpenses[trans->getCategory()] += trans->getAmount();
            }
            count++;
        }
    }

    if (count == 0) {
        std::cout << "该月份暂无记录。" << std::endl;
    } else {
        std::cout << "交易笔数: " << count << std::endl;
        std::cout << "收入总额: " << std::fixed << std::setprecision(2) << monthlyIncome << std::endl;
        std::cout << "支出总额: " << std::fixed << std::setprecision(2) << monthlyExpense << std::endl;
        std::cout << "净收入: " << std::fixed << std::setprecision(2) << (monthlyIncome - monthlyExpense) << std::endl;

        // 显示预算对比
        double monthlyBudget = budget.getMonthlyBudget(yearMonth);
        if (monthlyBudget > 0) {
            std::cout << "\n--- 预算执行情况 ---" << std::endl;
            std::cout << "月度预算: " << std::fixed << std::setprecision(2) << monthlyBudget << std::endl;
            std::cout << "实际支出: " << std::fixed << std::setprecision(2) << monthlyExpense << std::endl;
            std::cout << "预算余额: " << std::fixed << std::setprecision(2) << (monthlyBudget - monthlyExpense) << std::endl;

            double usage = budget.getMonthlyBudgetUsage(yearMonth, monthlyExpense);
            std::cout << "预算使用率: " << std::fixed << std::setprecision(1) << usage << "%" << std::endl;

            if (budget.checkMonthlyBudgetExceeded(yearMonth, monthlyExpense)) {
                double exceeded = monthlyExpense - monthlyBudget;
                std::cout << "⚠️  警告：超出预算 " << std::fixed << std::setprecision(2) << exceeded << " 元！" << std::endl;
            }
        }

        // 显示各类别支出情况
        if (!categoryExpenses.empty()) {
            std::cout << "\n--- 类别支出明细 ---" << std::endl;
            for (const auto& pair : categoryExpenses) {
                std::cout << "  " << pair.first << ": "
                          << std::fixed << std::setprecision(2) << pair.second;

                // 检查类别预算
                double catBudget = budget.getCategoryBudget(pair.first);
                if (catBudget > 0) {
                    double catUsage = budget.getCategoryBudgetUsage(pair.first, pair.second);
                    std::cout << " (预算: " << catBudget << ", 使用率: "
                              << std::fixed << std::setprecision(1) << catUsage << "%)";
                    if (budget.checkCategoryBudgetExceeded(pair.first, pair.second)) {
                        std::cout << " ⚠️ 超支";
                    }
                }
                std::cout << std::endl;
            }
        }
    }
    std::cout << "================================" << std::endl;
}

bool BudgetManager::saveToFile() const {
    std::ofstream file(dataFile);
    if (!file.is_open()) {
        std::cerr << "无法打开文件进行写入。" << std::endl;
        return false;
    }

    for (const auto& trans : transactions) {
        file << (trans->getType() == TransactionType::INCOME ? "INCOME" : "EXPENSE") << "|"
             << trans->getDate() << "|"
             << trans->getAmount() << "|"
             << trans->getCategory() << "|"
             << trans->getNote() << std::endl;
    }

    file.close();
    return true;
}

bool BudgetManager::loadFromFile() {
    std::ifstream file(dataFile);
    if (!file.is_open()) {
        return false;
    }

    transactions.clear();
    std::string line;

    while (std::getline(file, line)) {
        std::istringstream iss(line);
        std::string typeStr, date, category, note;
        double amount;

        if (std::getline(iss, typeStr, '|') &&
            std::getline(iss, date, '|') &&
            (iss >> amount) && iss.ignore() &&
            std::getline(iss, category, '|') &&
            std::getline(iss, note)) {

            TransactionType type = (typeStr == "INCOME") ? TransactionType::INCOME : TransactionType::EXPENSE;
            auto transaction = std::make_shared<Transaction>(date, amount, category, note, type);
            transactions.push_back(transaction);
        }
    }

    file.close();
    return true;
}

void BudgetManager::displayByAmountRange(double minAmount, double maxAmount) const {
    if (minAmount > maxAmount) {
        std::cout << "错误：最小金额不能大于最大金额！" << std::endl;
        return;
    }

    std::cout << "\n========== 金额范围：" << std::fixed << std::setprecision(2)
              << minAmount << " - " << maxAmount << " ==========" << std::endl;

    bool found = false;
    for (const auto& trans : transactions) {
        if (trans->getAmount() >= minAmount && trans->getAmount() <= maxAmount) {
            trans->display();
            found = true;
        }
    }

    if (!found) {
        std::cout << "该金额范围内暂无记录。" << std::endl;
    }
    std::cout << "================================" << std::endl;
}

void BudgetManager::searchByNote(const std::string& keyword) const {
    std::cout << "\n========== 搜索关键词：\"" << keyword << "\" ==========" << std::endl;

    bool found = false;
    for (const auto& trans : transactions) {
        if (trans->getNote().find(keyword) != std::string::npos) {
            trans->display();
            found = true;
        }
    }

    if (!found) {
        std::cout << "未找到包含该关键词的记录。" << std::endl;
    }
    std::cout << "================================" << std::endl;
}

void BudgetManager::displayRecentTransactions(int count) const {
    if (transactions.empty()) {
        std::cout << "暂无记录。" << std::endl;
        return;
    }

    std::cout << "\n========== 最近 " << count << " 条记录 ==========" << std::endl;

    // 创建一个副本并按日期降序排序
    auto sortedTrans = transactions;
    std::sort(sortedTrans.begin(), sortedTrans.end(),
              [](const auto& a, const auto& b) {
                  return a->getDate() > b->getDate();
              });

    int displayed = 0;
    for (const auto& trans : sortedTrans) {
        if (displayed >= count) break;
        trans->display();
        displayed++;
    }

    std::cout << "================================" << std::endl;
}

void BudgetManager::displayAllTransactionsSortedByDate(bool ascending) const {
    if (transactions.empty()) {
        std::cout << "暂无记录。" << std::endl;
        return;
    }

    std::cout << "\n========== 所有记录（按日期"
              << (ascending ? "升序" : "降序") << "）==========" << std::endl;

    auto sortedTrans = transactions;
    std::sort(sortedTrans.begin(), sortedTrans.end(),
              [ascending](const auto& a, const auto& b) {
                  return ascending ? (a->getDate() < b->getDate())
                                   : (a->getDate() > b->getDate());
              });

    for (const auto& trans : sortedTrans) {
        trans->display();
    }
    std::cout << "================================" << std::endl;
}

void BudgetManager::displayAllTransactionsSortedByAmount(bool ascending) const {
    if (transactions.empty()) {
        std::cout << "暂无记录。" << std::endl;
        return;
    }

    std::cout << "\n========== 所有记录（按金额"
              << (ascending ? "升序" : "降序") << "）==========" << std::endl;

    auto sortedTrans = transactions;
    std::sort(sortedTrans.begin(), sortedTrans.end(),
              [ascending](const auto& a, const auto& b) {
                  return ascending ? (a->getAmount() < b->getAmount())
                                   : (a->getAmount() > b->getAmount());
              });

    for (const auto& trans : sortedTrans) {
        trans->display();
    }
    std::cout << "================================" << std::endl;
}

double BudgetManager::getMonthlyExpense(const std::string& yearMonth) const {
    double expense = 0.0;
    for (const auto& trans : transactions) {
        if (trans->getDate().substr(0, 7) == yearMonth && trans->getType() == TransactionType::EXPENSE) {
            expense += trans->getAmount();
        }
    }
    return expense;
}

double BudgetManager::getCategoryExpense(const std::string& category) const {
    double expense = 0.0;
    for (const auto& trans : transactions) {
        if (trans->getCategory() == category && trans->getType() == TransactionType::EXPENSE) {
            expense += trans->getAmount();
        }
    }
    return expense;
}

double BudgetManager::getMonthlyExpenseByCategory(const std::string& yearMonth, const std::string& category) const {
    double expense = 0.0;
    for (const auto& trans : transactions) {
        if (trans->getDate().substr(0, 7) == yearMonth &&
            trans->getCategory() == category &&
            trans->getType() == TransactionType::EXPENSE) {
            expense += trans->getAmount();
        }
    }
    return expense;
}

void BudgetManager::displayBudgetStatus(const std::string& yearMonth) const {
    double monthlyBudget = budget.getMonthlyBudget(yearMonth);
    if (monthlyBudget == 0.0) {
        std::cout << "该月份未设置预算。" << std::endl;
        return;
    }

    double actualExpense = getMonthlyExpense(yearMonth);
    double usage = budget.getMonthlyBudgetUsage(yearMonth, actualExpense);
    double remaining = monthlyBudget - actualExpense;

    std::cout << "\n========== " << yearMonth << " 预算执行情况 ==========" << std::endl;
    std::cout << "月度预算: " << std::fixed << std::setprecision(2) << monthlyBudget << std::endl;
    std::cout << "实际支出: " << std::fixed << std::setprecision(2) << actualExpense << std::endl;
    std::cout << "预算余额: " << std::fixed << std::setprecision(2) << remaining << std::endl;
    std::cout << "使用率: " << std::fixed << std::setprecision(1) << usage << "%" << std::endl;

    if (budget.checkMonthlyBudgetExceeded(yearMonth, actualExpense)) {
        std::cout << "\n⚠️  警告：已超出预算 "
                  << std::fixed << std::setprecision(2) << (actualExpense - monthlyBudget)
                  << " 元！" << std::endl;
    } else if (usage > 80.0) {
        std::cout << "\n⚠️  提示：预算使用已超过80%，请注意控制支出。" << std::endl;
    } else {
        std::cout << "\n✓ 预算执行正常。" << std::endl;
    }
    std::cout << "================================" << std::endl;
}

void BudgetManager::displayCategoryBudgetStatus() const {
    const auto& categoryBudgets = budget.getCategoryBudgets();

    if (categoryBudgets.empty()) {
        std::cout << "暂未设置类别预算。" << std::endl;
        return;
    }

    std::cout << "\n========== 类别预算执行情况 ==========" << std::endl;

    for (const auto& pair : categoryBudgets) {
        const std::string& category = pair.first;
        double budgetAmount = pair.second;
        double actualExpense = getCategoryExpense(category);
        double usage = budget.getCategoryBudgetUsage(category, actualExpense);

        std::cout << "\n类别: " << category << std::endl;
        std::cout << "  预算: " << std::fixed << std::setprecision(2) << budgetAmount << std::endl;
        std::cout << "  实际: " << std::fixed << std::setprecision(2) << actualExpense << std::endl;
        std::cout << "  余额: " << std::fixed << std::setprecision(2) << (budgetAmount - actualExpense) << std::endl;
        std::cout << "  使用率: " << std::fixed << std::setprecision(1) << usage << "%" << std::endl;

        if (budget.checkCategoryBudgetExceeded(category, actualExpense)) {
            std::cout << "  ⚠️  超出预算 "
                      << std::fixed << std::setprecision(2) << (actualExpense - budgetAmount)
                      << " 元" << std::endl;
        }
    }

    std::cout << "================================" << std::endl;
}
